package cn.seaboot.admin.starter;

import cn.seaboot.admin.mvc.argument.ArgumentResolver;
import cn.seaboot.admin.mvc.response.ApplicationHandlerExceptionResolver;
import cn.seaboot.admin.starter.upload.UploadProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;

/**
 * 应用配置总控
 *
 * @author ChenSS on 2017年8月21日
 * @author 12614 on 2018/5/11.
 */
@Configuration
public class ApplicationConfigurer implements WebMvcConfigurer {
    private Logger logger = LoggerFactory.getLogger(ApplicationConfigurer.class);

    @Resource
    private UploadProperties uploadProperties;

    /**
     * spring-integration-core 包中有个冲突的 integrationConversionService
     */
    @Resource
    @Qualifier("mvcConversionService")
    private GenericConversionService conversionService;

    @PostConstruct
    public void init(){
    }

    /**
     * 请求拦截
     *
     * @param registry -
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //  .addPathPatterns() 是配置需要拦截的路径
        //  .excludePathPatterns() 用于排除拦截
        //  registry.addInterceptor(new TestInterceptor());
    }

    /**
     * 大部分文件，都有对应于业务的文件下载接口，访问会经过权限的过滤；
     *
     * 开放此接口的话，知道文件存储路径，即可以通过seaboot/file路径访问，基于tomcat原生功能实现，不受权限管理。
     *
     * @param registry -
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        if (Boolean.TRUE.equals(uploadProperties.getPublic())) {
            registry.addResourceHandler("/seaboot/file/**").addResourceLocations("file:" + uploadProperties.getRoot());
            logger.info("【Configuration】Open resource directory：{}", uploadProperties.getRoot());
        }
    }

    /**
     * 异常处理机制
     *
     * @param resolvers -
     */
    @Override
    public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
        if (!resolvers.isEmpty()) {
            resolvers.removeIf(resolver -> resolver instanceof DefaultHandlerExceptionResolver);
        }
        resolvers.add(0, new ApplicationHandlerExceptionResolver());
    }

    /**
     * 函数参数分解器
     *
     * @param argumentResolvers -
     */
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(0, new ArgumentResolver(conversionService));
    }
}
